/**
*
Java Diagram Package; An extremely flexible and fast multipurpose diagram
component for Swing.
Copyright (C) 2001 Eric Crahen <crahen@cse.buffalo.edu>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package diagram.figures;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import diagram.Figure;
/**
* @class PolygonFigure
*
* @date 08-20-2001
* @author Eric Crahen
* @version 1.0
*
*/
public class PolygonFigure extends Polygon
implements Cloneable, Figure, Serializable {
/**
* Get the rectangular bounds of this figure.
*
* @param Rectangle2D, use to avoid allocating a new object
* @return Rectangle2D
*/
public Rectangle2D getBounds2D(Rectangle2D rc) {
if(rc == null)
return new Rectangle2D.Double(bounds.x, bounds.y, bounds.width, bounds.height);
rc.setRect(bounds.x, bounds.y, bounds.width, bounds.height);
return rc;
}
/**
* Get the center of this figure.
*
* @param Point2D use to avoid allocating a new object
* @return Point2D
*/
public Point2D getCenter(Point2D pt) {
double centerX = bounds.x + bounds.width/2;
double centerY = bounds.y + bounds.height/2;
if(pt == null)
return new Point2D.Double(centerX, centerY);
pt.setLocation(centerX, centerY);
return pt;
}
/**
* Translate this figure.
*
* @param double
* @param double
*/
public void translate(double x, double y) {
super.translate((int)x, (int)y);
}
/**
* Point on the boundary of this figure closest to some
* point outside this figures.
*
* @param Point2D point outside this Figure to connect to
* @param Point2D use to avoid allocating a new object
*
* @return Point2D
*/
public Point2D getConnection(Point2D ptFrom, Point2D pt) {
if(contains(ptFrom)) {
if(pt == null)
pt = new Point2D.Double();
pt.setLocation(ptFrom);
return pt;
}
// compute the intersection of the line segment passing through
// (x0,y0) and (x1,y1) with the ray passing through
// (xCenter, yCenter) and (px,py)
double x0,x1,y0,y1;
// Get the angle
double centerX = bounds.x + bounds.width/2;
double centerY = bounds.y + bounds.height/2;
double dy = (ptFrom.getY() - centerY);
double dx = (ptFrom.getX() - centerX);
double theta = Math.atan2(dy, dx);
double px = centerX + Math.cos(theta);
double py = centerY + Math.sin(theta);
double A = 0, B = 0, max = 0;
x1 = this.xpoints[this.npoints-1];
y1 = this.ypoints[this.npoints-1];
for(int i=0; i < this.npoints; i++) {
x0 = x1;
y0 = y1;
x1 = this.xpoints[i];
y1 = this.ypoints[i];
double n = (x0-centerX)*(py-centerY) - (y0-centerY)*(px-centerX);
double m = (y1-y0)*(px-centerX) - (x1-x0)*(py-centerY);
double t = n/m;
if(0 <= t && t <= 1) {
double tx = x0 + (x1-x0)*t;
double ty = y0 + (y1-y0)*t;
boolean xGood = (tx >= centerX && px >= centerX)||(tx < centerX && px < centerX);
boolean yGood = (ty >= centerY && py >= centerY)||(ty < centerY && py < centerY);
if(xGood && yGood) {
double r = (tx-centerX)*(tx-centerX) + (ty-centerY)*(ty-centerY);
if(r > max) {
A = tx;
B = ty;
max = r;
}
}
}
}
if(pt == null)
return new Point2D.Double(A, B);
pt.setLocation(A, B);
return pt;
}
/**
* Get the anchor for the Figure. This is usually the center
* of the Figure but does not always have to be.
*
* @param Point2D use to avoid allocating a new object
*
* @return Point2D
*/
public Point2D getAnchor(Point2D pt) {
return getCenter(pt);
}
/**
* Reshape this figure.
*
* @param double
* @param double
* @param double
* @param double
*/
public void setBounds(double x, double y, double w, double h) {
}
public Object clone() {
PolygonFigure fig = new PolygonFigure();
fig.bounds = (Rectangle)bounds.clone();
fig.npoints = npoints;
fig.xpoints = new int[xpoints.length];
fig.ypoints = new int[ypoints.length];
System.arraycopy(xpoints, 0, fig.xpoints, 0, xpoints.length);
System.arraycopy(ypoints, 0, fig.ypoints, 0, ypoints.length);
return fig;
}
/**
* Generate a hashcode that will not be affected by the bounds of the
* Figure.
*/
private static int generateLocalHash() {
Class c = PolygonFigure.class;
return (c.hashCode() + figureId++);
}
private int hash = generateLocalHash();
private static int figureId = 0;
public int hashCode() {
return figureId;
}
}